package com.mhkj.common.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;

import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;

import com.alibaba.fastjson.JSONObject;
import com.mics.core.common.util.http.MySSLSocketFactory;  

public class HttpClientUtil {
	
	private static final int MAX_SIZE = 10485760;// http response 最大10M
	private static PoolingHttpClientConnectionManager connMgr;  
    private static RequestConfig requestConfig;  
    private static final int MAX_TIMEOUT = 7000;  
  
    static {  
        // 设置连接池  
        connMgr = new PoolingHttpClientConnectionManager();  
        // 设置连接池大小  
        connMgr.setMaxTotal(100);  
        connMgr.setDefaultMaxPerRoute(connMgr.getMaxTotal());  
  
        RequestConfig.Builder configBuilder = RequestConfig.custom();  
        // 设置连接超时  
        configBuilder.setConnectTimeout(MAX_TIMEOUT);  
        // 设置读取超时  
        configBuilder.setSocketTimeout(MAX_TIMEOUT);  
        // 设置从连接池获取连接实例的超时  
        configBuilder.setConnectionRequestTimeout(MAX_TIMEOUT);  
        // 在提交请求之前 测试连接是否可用  
        configBuilder.setStaleConnectionCheckEnabled(true);  
        requestConfig = configBuilder.build();  
    }  
	
	
	
	private static CloseableHttpClient ssl() {  
        CloseableHttpClient httpclient = null;  
        try {  
//            KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());  
//            FileInputStream instream = new FileInputStream(new File("d:\\tomcat.keystore"));  
//            try {  
//                // 加载keyStore d:\\tomcat.keystore    
//                trustStore.load(instream, "123456".toCharArray());  
//            } catch (CertificateException e) {  
//                e.printStackTrace();  
//            } catch (Exception e) {  
//                e.printStackTrace();  
//            } finally {  
//                try {  
//                    instream.close();  
//                } catch (Exception ignore) {  
//                }  
//            }  
//            // 相信自己的CA和所有自签名的证书  
            //SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()).build();  
            SSLContext sslcontext = SSLContext.getInstance("TLS");
           
        	// 只允许使用TLSv1协议  
//            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null,  
//                    SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);  
            SSLConnectionSocketFactory sslsf=new SSLConnectionSocketFactory(sslcontext,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 
            ClientConnectionManager ccm =httpclient.getConnectionManager();
            SchemeRegistry sr = ccm.getSchemeRegistry();
    		sr.register(new Scheme("https", MySSLSocketFactory.getInstance(), 443));
            httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();  
            // 创建http请求(get方式)  
//            HttpGet httpget = new HttpGet("https://localhost:8443/myDemo/Ajax/serivceJ.action");  
//            System.out.println("executing request" + httpget.getRequestLine());  
//            CloseableHttpResponse response = httpclient.execute(httpget);  
//            try {  
//                HttpEntity entity = response.getEntity();  
//                System.out.println("----------------------------------------");  
//                System.out.println(response.getStatusLine());  
//                if (entity != null) {  
//                    System.out.println("Response content length: " + entity.getContentLength());  
//                    System.out.println(EntityUtils.toString(entity));  
//                    EntityUtils.consume(entity);  
//                }  
//            } finally {  
//                response.close();  
//            }  
//        } catch (ParseException e) {  
//            e.printStackTrace();  
//        } catch (IOException e) {  
//            e.printStackTrace();  
//        } catch (KeyManagementException e) {  
//            e.printStackTrace();  
//        } catch (NoSuchAlgorithmException e) {  
//            e.printStackTrace();  
//        } catch (KeyStoreException e) {  
//            e.printStackTrace();  
//        }
	 } catch (Exception e) {  
         e.printStackTrace();  
     } 
        finally {  
            if (httpclient != null) {  
                try {  
                    httpclient.close();  
                } catch (IOException e) {  
                    e.printStackTrace();  
                }  
            }  
        }
        return httpclient;
    }
	
	public static CloseableHttpClient createSSLClientDefault(){

		try { 
				SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
	                 //信任所有
	                 public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
	                     return true;
	                 }
	             }).build();
	             SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
	             return HttpClients.custom().setSSLSocketFactory(sslsf).build();
	         } catch (KeyManagementException e) {
	             e.printStackTrace();
	         } catch (NoSuchAlgorithmException e) {
	             e.printStackTrace();
	         } catch (KeyStoreException e) {
	             e.printStackTrace();
	         }
	         return  HttpClients.createDefault();
		}
	
	public static String postSSL(String url,Map<String,String> map){
		CloseableHttpClient httpclient = null;
		CloseableHttpResponse response=null;
		HttpPost httppost=null;
        String result = null;  
	        try{  
	        	httpclient = createSSLClientDefault();
	            httppost = new HttpPost(url);  
	            JSONObject json=new JSONObject();
	            httppost.setHeader("Content-type","application/json;charset=UTF-8");
	            //设置参数  
	            Iterator iterator = map.entrySet().iterator();  
	            while(iterator.hasNext()){  
	                Entry<String,String> elem = (Entry<String, String>) iterator.next();  
	                json.put(elem.getKey(),elem.getValue());
	            }
	            StringEntity entity=new StringEntity(json.toString(),"UTF-8");
	            httppost.setEntity(entity);  
	            response = httpclient.execute(httppost);
	            if(response != null){  
	                HttpEntity resEntity = response.getEntity();  
	                if(resEntity != null){  
	                    result = EntityUtils.toString(resEntity, "UTF-8");  
	                }
	            }  
	            
	        }catch(Exception ex){  
	            ex.printStackTrace();  
	        }finally {
	        	try {
	        		if(response!=null)
	        			response.close();
	        		if(httppost!=null)
	        			httppost.releaseConnection();
	        		if(httpclient!=null)
	        			httpclient.close();
	        		
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
	        return result;  
	}
	
	
	public static String doPostSSL(String apiUrl, Map<String,String> map) {  
        CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory()).setConnectionManager(connMgr).setDefaultRequestConfig(requestConfig).build();  
        HttpPost httpPost = new HttpPost(apiUrl);  
        CloseableHttpResponse response = null;  
        String httpStr = null;  
        JSONObject json=new JSONObject();
        //设置参数  
        Iterator iterator = map.entrySet().iterator();  
        while(iterator.hasNext()){  
            Entry<String,String> elem = (Entry<String, String>) iterator.next();  
            json.put(elem.getKey(),elem.getValue());
        }
        try {  
            httpPost.setConfig(requestConfig);  
            StringEntity stringEntity = new StringEntity(json.toString(),"UTF-8");//解决中文乱码问题  
            stringEntity.setContentEncoding("UTF-8");  
            stringEntity.setContentType("application/json");  
            httpPost.setEntity(stringEntity);  
            response = httpClient.execute(httpPost);  
            int statusCode = response.getStatusLine().getStatusCode();  
            if (statusCode != HttpStatus.SC_OK) {  
                return null;  
            }  
            HttpEntity entity = response.getEntity();  
            if (entity == null) {  
                return null;  
            }  
            httpStr = EntityUtils.toString(entity, "utf-8");  
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            if (response != null) {  
                try {  
                    EntityUtils.consume(response.getEntity());  
                } catch (IOException e) {  
                    e.printStackTrace();  
                }  
            }  
        }  
        return httpStr;  
    }  
	/** 
     * 发送 post请求访问本地应用并根据传递参数不同返回不同结果 
	 * @throws IOException 
	 * @throws ClientProtocolException 
     */  
    public static String post(String url,Map<String,String> map) throws ClientProtocolException, IOException {  
    	String result = null;
    	// 创建默认的httpClient实例.    
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory()).setConnectionManager(connMgr).setDefaultRequestConfig(requestConfig).build();  

        // 创建httppost    
        HttpPost httppost = new HttpPost(url);  
        CloseableHttpResponse response= null ;
        JSONObject json = new JSONObject();
        //设置参数  
        Iterator iterator = map.entrySet().iterator();  
        while(iterator.hasNext()){  
            Entry<String,String> elem = (Entry<String, String>) iterator.next();  
            json.put(elem.getKey(),elem.getValue());
        }
        // 创建参数队列    
        try {          	
        	
            httppost.setConfig(requestConfig);  
            StringEntity stringEntity = new StringEntity(json.toString(),"UTF-8");//解决中文乱码问题  
            stringEntity.setContentEncoding("UTF-8");  
            stringEntity.setContentType("application/json");  
            httppost.setEntity(stringEntity);
            
            response = httpclient.execute(httppost);
            if(response != null){  
                HttpEntity resEntity = response.getEntity();  
                if(resEntity != null){  
                    result = EntityUtils.toString(resEntity, "UTF-8");  
                }
            }
        } catch (ClientProtocolException e) {  
            e.printStackTrace();  
        } catch (UnsupportedEncodingException e1) {  
            e1.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  finally {  
            // 关闭连接,释放资源 
        	if(httppost!=null)
    			httppost.releaseConnection();
        	/*try {
        		if(response!=null)
        			//response.close();
        		if(httppost!=null)
        			httppost.releaseConnection();
        		if(httpclient!=null)
        			httpclient.close();
        		
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}*/
        }
        return result;
    }  
    
    public static String sendHttpPost(HttpPost httpPost) {
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse response = null;
		HttpEntity entity = null;
		String responseContent = null;
		try {
			// 创建默认的httpClient实例.
			httpClient = HttpClients.createDefault();
			httpPost.setConfig(requestConfig);
			// 执行请求
			response = httpClient.execute(httpPost);
			entity = response.getEntity();
			responseContent = EntityUtils.toString(entity, "UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 关闭连接,释放资源
				if (response != null) {
					response.close();
				}
				if (httpClient != null) {
					httpClient.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return responseContent;
	}

    
    public static String postBySSL(String url,String params) {  
    	String result = null;
    	// 创建默认的httpClient实例.    
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(createSSLConnSocketFactory()).setConnectionManager(connMgr).setDefaultRequestConfig(requestConfig).build();  
        // 创建httppost    
        HttpPost httppost = new HttpPost(url);  
        CloseableHttpResponse response=null;

        // 创建参数队列    
        try {          	
        	StringEntity stringEntity = new StringEntity(params, "UTF-8");
			stringEntity.setContentType("application/x-www-form-urlencoded");
            httppost.setConfig(requestConfig);  
            httppost.setEntity(stringEntity);  

            response = httpclient.execute(httppost);
            if(response != null){  
                HttpEntity resEntity = response.getEntity();  
                if(resEntity != null){  
                    result = EntityUtils.toString(resEntity, "UTF-8");  
                }
            }  
            
        } catch (ClientProtocolException e) {  
            e.printStackTrace();  
        } catch (UnsupportedEncodingException e1) {  
            e1.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  finally {  
            // 关闭连接,释放资源    
        	try {
        		if(response!=null)
        			response.close();
        		if(httppost!=null)
        			httppost.releaseConnection();
//        		if(httpclient!=null)
//        			httpclient.close();
        		
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
        }
        return result;
    }  
  
    
    /** 
     * 发送 get请求 
     */  
    public static String get(String url) {  
        CloseableHttpClient httpclient = HttpClients.createDefault();  
        CloseableHttpResponse response=null;
        try {
            // 创建httpget.    
            HttpGet httpget = new HttpGet(url);
            httpget.addHeader("Accept","application/json");
            // 执行get请求.    
            response = httpclient.execute(httpget);  
            HttpEntity entity = response.getEntity();  
            if (entity != null) {
                return EntityUtils.toString(entity);
            }  
        
        } catch (ClientProtocolException e) {  
            e.printStackTrace();  
        } catch (ParseException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        } finally {  
            // 关闭连接,释放资源    
            try {
            	if(response!=null)
        			response.close();
            	if(httpclient!=null)
            		httpclient.close();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }
        return "";
    }
    static byte[] getResponseData(InputStream is) throws IOException {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		byte[] buf = new byte[2046];
		int total = 0, len = 0;
		try {
			while ((len = is.read(buf)) > 0) {
				total += len;
				if (total > MAX_SIZE) {
					throw new IOException("response body size over 10M");
				}
				baos.write(buf, 0, len);
			}
		} finally {
			if (is != null) {
				is.close();
			}
		}
		return baos.toByteArray();
	}

	static String getResponseAsString(InputStream is) throws IOException {
		String res = null;
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		byte[] buf = new byte[2046];
		int total = 0, len = 0;
		try {
			while ((len = is.read(buf)) > 0) {
				total += len;
				if (total > MAX_SIZE) {
					throw new IOException("response body size over 10M");
				}
				baos.write(buf, 0, len);
			}
		} finally {
			if (is != null) {
				is.close();
			}
		}
		try {
			res = new String(baos.toByteArray(), "utf-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return res;
	}

    /** 
     * 创建SSL安全连接 
     * 
     * @return 
     */  
    private static SSLConnectionSocketFactory createSSLConnSocketFactory() {  
        SSLConnectionSocketFactory sslsf = null;  
        try {  
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {  
  
                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {  
                    return true;  
                }  
            }).build();  
            sslsf = new SSLConnectionSocketFactory(sslContext, new X509HostnameVerifier() {  
  
                @Override  
                public boolean verify(String arg0, SSLSession arg1) {  
                    return true;  
                }  
  
                @Override  
                public void verify(String host, SSLSocket ssl) throws IOException {  
                }  
  
                @Override  
                public void verify(String host, X509Certificate cert) throws SSLException {  
                }  
  
                @Override  
                public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException {  
                }  
            });  
        } catch (GeneralSecurityException e) {  
            e.printStackTrace();  
        }  
        return sslsf;  
    }  
/*    public static void main(String args[]){
    	
    }*/
  
}
